﻿using Commons;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using RMSIService;
using RMSModel;
using RMSModel.Models;
using RMSModel.VMModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
namespace RMSServiceImpl
{
    public class WXApiServiceImpl : WXApiIService
    {
        private readonly RMSDB db;

        public WXApiServiceImpl(RMSDB db)
        {
            this.db = db;
        }
        public ResultType<Dictionary<string,object>> login_by_weixin(VMParamEntity param)
        {
            ResultType<Dictionary<string, object>> result = new ResultType<Dictionary<string, object>>();
            var tran = db.Database.BeginTransaction();
            try
            {
                string url = "https://api.weixin.qq.com/sns/jscode2session?appid={0}&secret={1}&js_code={2}&grant_type=authorization_code";
                url = string.Format(url, "wx5b28a9694b82aa4c", "d1cf97d4e9071189a75326c28229957c", param.code);
                var responsedata= JsonConvert.DeserializeObject<Dictionary<string, string>>(DoGet(url).Result);
                if (responsedata.ContainsKey("errcode"))
                {
                    result.ResultCode = 1;
                    result.ResultMsg = "errcode:"+ responsedata["errcode"]+ ",errmsg:"+ responsedata["errmsg"];
                    return result;
                }
                string openid = responsedata["openid"];
                string session_key= responsedata["session_key"];
                var userd = db.shopuser.FromSqlRaw(string.Format("select * from shopuser where openid='{0}'", openid));
                if (userd.Count() > 0)
                {
                    shopuser user = userd.First();
                    user.lastlogintime = DateTime.Now;
                    db.shopuser.Update(user);
                    db.SaveChanges();
                    result.Data.Add("token", db.shopusertoken.FromSqlRaw(string.Format("select * from shopusertoken where user_id={0}", user.id)).First().token);
                    result.Data.Add("userInfo",user);
                }
                else
                {
                    shopuser user = param.userInfo;
                    user.openid = openid;
                    user.registertime = DateTime.Now;
                    user.lastlogintime=DateTime.Now;
                    user=db.shopuser.Add(user).Entity;
                    db.SaveChanges();

                    string token = MD5Utils.GetMD5_32(openid + session_key);
                    shopusertoken usertoken = new shopusertoken() { update_time = DateTime.Now,token=token,expire_time=DateTime.Now.AddDays(30),user_id= user.id };
                    db.shopusertoken.Add(usertoken);
                    db.SaveChanges();
                    result.Data.Add("token", token);
                    result.Data.Add("userInfo", user);
                }
                tran.Commit();

            }
            catch(Exception ex)
            {
                tran.Rollback();
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }
            return result;
        }

        private static async Task<string> DoGet(string requestUrl)
        {
            string responseBody = string.Empty;
            using (HttpClient httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Add("Method", "Get");
                httpClient.DefaultRequestHeaders.Add("KeepAlive", "false");
                httpClient.DefaultRequestHeaders.Add("UserAgent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11");

                HttpResponseMessage response = await httpClient.GetAsync(requestUrl);
                response.EnsureSuccessStatusCode();
                responseBody = await response.Content.ReadAsStringAsync();
            }
            return responseBody;
        }
        public ResultType<List<goodstype>> GetAllGoodType()
        {
            ResultType<List<goodstype>> result = new ResultType<List<goodstype>>();
            try
            {
                result.Data = db.goodstype.ToList().Where(p=>p.level.Equals("LV1")).Where(p=>p.status==true).ToList();

            }catch(Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }
            return result;
        }

        public ResultType<int> GetGoodsCount()
        {
            ResultType<int> result = new ResultType<int>();
            try
            {
                result.Data = db.goods.ToList().Count;

            }
            catch (Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }
            return result;
        }

        public ResultType<List<goodstype>> GetGoodTypeById(int id)
        {
            ResultType<List<goodstype>> result = new ResultType<List<goodstype>>();
            try
            {
                result.Data = db.goodstype.FromSqlRaw(string.Format("select * from goodstype where parentid={0}",id)).Where(p => p.status == true).ToList();

            }
            catch (Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }
            return result;
        }

        public ResultType<Dictionary< string,object>> GetGoodById(int id,int page,int size)
        {
            ResultType<Dictionary<string, object>> result = new ResultType<Dictionary<string, object>>();
            try
            {
                string sql = string.Format("select* from goods where categoryid ={0} limit {1},{2}",id,(page-1)*size,size);
                result.Data.Add("goodsList", db.goods.FromSqlRaw(sql).ToList());
                result.Data.Add("currentPage", page);
                int number = db.goods.Count()/size;
                if (number % 10 != 0) number++;
                result.Data.Add("totalPages", number);
            }
            catch (Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }
            return result;
        }

        public ResultType<VMGoods> GetGoodsDetailById(int id)
        {
            ResultType<VMGoods> result = new ResultType<VMGoods>();
            try
            {
                goods g = db.goods.Find(id);
                VMGoods vng = new VMGoods() { categoryid = g.categoryid, createtime = g.createtime, createuser = g.createuser, goodnumber = g.goodnumber, goodsellnumber = g.goodsellnumber, goodsn = g.goodsn, id = g.id, listpicurl = g.listpicurl, masterpicurl = g.masterpicurl, name = g.name, price = g.price, sort = g.sort, status = g.status, updatetime = g.updatetime, updateuser = g.updateuser };
                var imageList = db.goodsimagelist.FromSqlRaw(string.Format("select * from goodsimagelist where goodsid={0}", id));
                if (imageList.Count() > 0)
                {
                    vng.imageList = imageList.Select(p => p.imagelisturl).ToList();
                }
                var goodhtml = db.gooddetailshtml.FromSqlRaw(string.Format("select * from gooddetailshtml where goodsid={0}", id));
                if (goodhtml.Count() > 0)
                {
                    vng.goodhtml = goodhtml.Select(p => p.goodhtml).First();
                }

                result.Data = vng;
            }
            catch (Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }

            return result;
        }

        public ResultType<int> AddOrder(VMOrder vmo)
        {
            ResultType<int> result = new ResultType<int>();
            var tran = db.Database.BeginTransaction();
            try
            {
                order o = new order() { address=vmo.address,shopuserid=vmo.shopuserid,addtime=vmo.addtime,city=vmo.city,consignee=vmo.consignee,district=vmo.district,mobile=vmo.mobile,orderprice=vmo.orderprice,province=vmo.province,orderstatus=0};
                o.ordersn=DateTime.Now.ToString("yyyyMMddhhmmss")+ DateTime.Now.Ticks.ToString().Substring(12,6)+o.shopuserid;
                o =db.orders.Add(o).Entity;
                db.SaveChanges();
                goods g = db.goods.Find(vmo.ordergoods[0]["id"]);
                g.goodnumber--;
                g.goodsellnumber++;
                db.goods.Attach(g);
                db.Entry(g).State = EntityState.Modified;
                db.SaveChanges();
                ordergoods og = new ordergoods() {goodid=vmo.ordergoods[0]["id"],number=vmo.ordergoods[0]["number"],orderid=o.id ,name=g.name,listpicurl = g.listpicurl};
                db.ordergoods.Add(og);
                db.SaveChanges();
                tran.Commit();
                result.Data = o.id;
            }
            catch (Exception ex)
            {
                tran.Rollback();
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }

            return result;
        }

        public ResultType<List<shopaddress>> GetAllShopAddress(int id)
        {
            ResultType<List<shopaddress>> result = new ResultType<List<shopaddress>>();
            try
            {
                result.Data = db.shopaddresses.FromSqlRaw(string.Format("select * from shopaddress where userid={0}", id)).ToList();
            }
            catch (Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }
            return result;
        }
        public ResultType<List<shopaddress>> GetAllShopAddress()
        {
            ResultType<List<shopaddress>> result = new ResultType<List<shopaddress>>();
            try
            {
                result.Data = db.shopaddresses.ToList();
            }
            catch (Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }
            return result;
        }
        public ResultType<shopaddress> GetDefaultShopAddressByUserId(int id)
        {
            ResultType<shopaddress> result=new ResultType<shopaddress>();
            try
            {
                result.Data=  db.shopaddresses.FromSqlRaw(string.Format("select * from shopaddress where userid={0} and isdefault=1", id)).First();
            }
            catch(Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }
            return result;
        }

        public ResultType AddShopAddress(shopaddress ad)
        {
            ResultType result = new ResultType();
            try
            {
                if (ad.isdefault == 1)
                {
                    shopaddress dad = db.shopaddresses.AsNoTracking().Where(p=>p.userid==ad.userid).Where(p => p.isdefault == 1).FirstOrDefault();
                    if (dad != null&&dad.id!=ad.id)
                    {
                        dad.isdefault = 0;
                        db.shopaddresses.Attach(dad);
                        db.Entry(dad).State = EntityState.Modified;
                        db.SaveChanges();
                    }

                }
                if (ad.id != 0)
                {
                    
                    db.shopaddresses.Attach(ad);
                    db.Entry(ad).State = EntityState.Modified;
                    db.SaveChanges();
                }
                else
                {
                    db.shopaddresses.Add(ad);
                    db.SaveChanges();
                }

            }
            catch (Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }
            return result;
        }

        public ResultType UpdateShopAddress(shopaddress ad)
        {
            ResultType result = new ResultType();
            try
            {
                db.shopaddresses.Attach(ad);
                db.Entry(db).State = EntityState.Modified;
                db.SaveChanges();
            }
            catch (Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }

            return result;
        }


        public ResultType<Dictionary<string,object>> Checkout(goods ad,int id)
        {
            ResultType<Dictionary<string, object>> result=new ResultType<Dictionary<string, object>>();
            try
            {
                goods g = db.goods.Find(ad.id);
                if (g.goodnumber < ad.goodnumber)
                {
                    result.ResultCode = 1;
                    result.ResultMsg = "抱歉你购买的物品库存不足！";
                    return result;
                }
                List<goods> data = new List<goods>();
                data.Add(g);
                result.Data.Add("checkedGoodsList", data);
                result.Data.Add("checkedAddress", GetDefaultShopAddressByUserId(id).Data);
            }
            catch (Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }
            return result;
        }

        public ResultType<List<sys_region>> GetRegionById(int id)
        {
            ResultType<List<sys_region>> result = new ResultType<List<sys_region>>();
            try
            {
                result.Data = db.sys_region.FromSqlRaw(string.Format("select * from sys_region where parent_id={0}",id)).ToList();
            }catch(Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg =ex.Message;
            }
            return result;
        }

        public ResultType<order> GetOrderById(int id)
        {
            ResultType<order> result = new ResultType<order>();
            try
            {
                result.Data = db.orders.Find(id);
            }catch(Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }
            return result;
        }

        public ResultType<Dictionary<string,object>> GetOrderByUserId(int page, int size, int userId)
        {
            ResultType<Dictionary<string, object>> result = new ResultType<Dictionary<string, object>>();
            try
            {
                //获取该用户订单信息
                string sql =  string.Format("select * from `order` where shopuserid={0} limit {1},{2}", userId, (page - 1) * size, size);
                var orderdata = db.orders.FromSqlRaw(sql).ToList();
                var orgooddata = db.ordergoods.ToList();//
                var gooddata = db.goods.ToList();
                List<VMOrder> vmorder = new List<VMOrder>(); 
                foreach (var o in orderdata)
                {
                    ///订单里面包括订单主体数据和订单物品数据
                    List<ordergoods> lgood = new List<ordergoods>();//订单中的商品
                    foreach (var so in orgooddata.Where(p=>p.orderid==o.id))
                    {
                        lgood.Add(so);
                    }
                    VMOrder vmo = new VMOrder(){ goodList = lgood,order = o};
                    vmorder.Add(vmo);
                }

                result.Data.Add("orderList", vmorder);
                result.Data.Add("currentPage", page);
                int number = db.orders.FromSqlRaw(string.Format("select * from `order` where shopuserid={0}",userId)).Count() / size;
                if (number % 10 != 0) number++;
                result.Data.Add("totalPages", number);

            }
            catch(Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }
            return result;
        }

        public ResultType<shopaddress> GetShopAddressById(int id)
        {
            ResultType<shopaddress> result = new ResultType<shopaddress>();
            try
            {
                result.Data = db.shopaddresses.Find(id);
            }
            catch (Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }

            return result;
        }


    }
}
